﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using log4net;
using SegIdenPC.Entidad;
using SegIdenPC.Herramientas;
using GS1.Utilitario;

namespace SegIdenPC.Formularios
{
    public partial class frmMantComponente : Form
    {
        #region --- Variables y Propiedades ---
        private static readonly ILog log = LogManager.GetLogger(typeof(frmMantComponente));

        private const string TITULO = "Mantenimiento de Componentes";
        private const string FORMATO_TOTAL_ENCONTRADOS = "Total componente encontrados: {0}";

        private const string DESCRIPCION = "Descripción";
        private string ESTADO = string.Empty;

        public enum OperacionMantenimiento
        {
            Nuevo,
            Editar
        }

        private OperacionMantenimiento tipoOperacion = OperacionMantenimiento.Nuevo;

        private enum Opcion
        {
            Abrir = 0,
            Nuevo = 1,
            Editar = 2,
            Grabar = 3,
            Cancelar = 4,
            Eliminar = 5
        }

        public Componente componenteActual { get; set; }
        #endregion

        #region --- Constructor ---
        public frmMantComponente()
        {
            InitializeComponent();
        }
        #endregion

        #region --- Eventos Formulario ---
        private void frmMantComponente_Load(object sender, EventArgs e)
        {
            cargarFormulario();
        }

        private void frmMantComponente_FormClosing(object sender, FormClosingEventArgs e)
        {
            finalizarFormulario();
        }

        private void tbtnAbrir_Click(object sender, EventArgs e)
        {
            abrir();
        }

        private void tbtnNuevo_Click(object sender, EventArgs e)
        {
            nuevo();
        }

        private void tbtnEditar_Click(object sender, EventArgs e)
        {
            editar();
        }

        private void tbtnGrabar_Click(object sender, EventArgs e)
        {
            grabar();
        }

        private void tbtnCancelar_Click(object sender, EventArgs e)
        {
            cancelar();
        }

        private void tbtnEliminar_Click(object sender, EventArgs e)
        {
            eliminar();
        }

        private void tbtnSalir_Click(object sender, EventArgs e)
        {
            salir();
        }

        private void btnBuscar_Click(object sender, EventArgs e)
        {
            buscar();
        }

        private void tabControl_Selecting(object sender, TabControlCancelEventArgs e)
        {
            if (!e.TabPage.Enabled) { e.Cancel = true; }
        }

        private void dgvListado_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            seleccionarComponente();
        }

        private void txtCriterio_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter) { buscar(); }
        }
        #endregion

        #region --- Metodos Propios ---
        private void cargarFormulario()
        {
            ListaGeneral listaEstado = null;

            try
            {
                Cursor.Current = Cursors.WaitCursor;

                // Activaciones de botones por rol
                controlBotonesPorRol();

                // Instanciando y creando listado de estado
                listaEstado = new ListaGeneral();
                listaEstado.Add(new General { codigo = Constantes.ESTADO_CODIGO_ACTIVO, descripcion = Constantes.ESTADO_DESCRIPCION_ACTIVO });
                listaEstado.Add(new General { codigo = Constantes.ESTADO_CODIGO_INACTIVO, descripcion = Constantes.ESTADO_DESCRIPCION_INACTIVO });

                // Desactivando el grupo de campo de informacion
                this.tabPagDatos.Enabled = false;

                // Estableciendo Ficha 0 como seleccion incial
                this.tabControl.SelectedIndex = 0;
                // Capturando evento selecting en el control Tab
                this.tabControl.Selecting += new TabControlCancelEventHandler(tabControl_Selecting);

                // Estableciendo a 0 el texto del total de registros encontrados.
                this.lblTotalRegistros.Text = string.Format(FORMATO_TOTAL_ENCONTRADOS, 0);

                // Desactivando el boton abrir.
                this.tbtnAbrir.Enabled = false;

                // Estableciendo parametros del Combo Criterio
                this.cboCriterio.Items.Add(DESCRIPCION);
                this.cboCriterio.SelectedIndex = 0;

                // Estableciendo datos del combo Estado
                this.cboEstado.DataSource = listaEstado;
                this.cboEstado.ValueMember = Constantes.GENERAL_CODIGO;
                this.cboEstado.DisplayMember = Constantes.GENERAL_DESCRIPCION;
                this.cboEstado.SelectedIndex = 0;

                // Estableciendo focus
                this.txtCriterio.Focus();

            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        private void finalizarFormulario()
        {
            this.tabControl.Selecting -= new TabControlCancelEventHandler(tabControl_Selecting);
        }

        private void pintarGrilla()
        {
            ListPersonalizada<Componente> listaComponentes = null;
            listaComponentes = (ListPersonalizada<Componente>)this.dgvListado.DataSource;

            if (listaComponentes != null)
            {
                for (int i = 0; i < listaComponentes.Count; i++)
                {
                    var componente = listaComponentes[i];
                    componente.estado = componente.estado.Equals(Constantes.ESTADO_CODIGO_INACTIVO) ? Constantes.ESTADO_DESCRIPCION_INACTIVO : Constantes.ESTADO_DESCRIPCION_ACTIVO;

                    if (componente.estado == Constantes.ESTADO_DESCRIPCION_INACTIVO)
                    {
                        this.dgvListado.Rows[i].DefaultCellStyle.BackColor = Color.FromArgb(255, 128, 128);
                    }
                }
            }
        }

        private bool validarEntradaBusqueda()
        {
            this.txtCriterio.Text = this.txtCriterio.Text.Trim();
            if (this.txtCriterio.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtCriterio, "Debe ingresar el valor de busqueda");
                return true;
            }

            if (this.txtCriterio.TextLength < 3)
            {
                Libreria.CampoNecesario(this.txtCriterio, "Debe ingresar por lo menos 3 caracteres para realizar la busqueda");
                return true;
            }

            return false;
        }

        private void listarComponentes(string criterio,
                                       string valor)
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            // Estableciendo operacion a ser enviada al Servicio REST
            operacion = new Operacion();
            operacion.numero = Constantes.OPERACION_LISTAR_COMPONENTES;

            operacion.componente = new Componente();
            operacion.componente.descripcion = valor;
            operacion.componente.estado = this.ESTADO;

            // Instanciando y ejecutando llamada al ServicioREST
            ConexionREST conexionREST = new ConexionREST();
            contenidoXML = conexionREST.ejecutarOperacion(operacion);

            // Obteniendo Objeto de Error
            OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

            // Validar si hay error
            if (operacionError != null)
            {
                Libreria.ShowMessageboxError(operacionError.descripcion);
                return;
            }

            // Obteniendo Objeto de ListaComponente
            ListaComponente listaComponente = contenidoXML.DeserializarTo<ListaComponente>();

            // Mostrar el total de registros encontrados
            this.lblTotalRegistros.Text = string.Format(FORMATO_TOTAL_ENCONTRADOS, listaComponente.lista.Count);

            // Se establece propiedad para evitar que genere nuevas columnas que no estan mapeadas en la grilla
            this.dgvListado.AutoGenerateColumns = false;

            // Se establece la fuente de datos de la grilla
            this.dgvListado.DataSource = listaComponente.lista;

            // Activando o desactivando boton Abrir
            this.tbtnAbrir.Enabled = listaComponente.lista.Count > 0;

            // Colorear grilla deacuerdo a criterios
            pintarGrilla();
        }

        private void buscar()
        {
            try
            {
                if (validarEntradaBusqueda()) { return; }

                // Listar componentes con el criterio y el valor ingresado
                listarComponentes(this.cboCriterio.Text, this.txtCriterio.Text);

                // Estableciendo focus al caja de texto de busqueda
                this.txtCriterio.Focus();
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }

        private void nuevo()
        {
            // Estableciendo estado de TagPage de Listado y datos
            this.tabPagListado.Enabled = false; this.tabPagDatos.Enabled = true;

            // Mostrar la segunda pagina del TabControl
            this.tabControl.SelectedIndex = 1;

            this.grpDatos.Enabled = true;
            this.cboEstado.Enabled = false;

            // Estableciendo los estados de los botones
            cambiarEstadoBotones(Opcion.Nuevo);

            // Limpiar los datos del formulario
            limpiarTodo();

            this.tipoOperacion = OperacionMantenimiento.Nuevo;

            // Estableciendo focus al caja de texto de descripcion
            this.txtDescripcion.Focus();
        }

        private void editar()
        {
            this.grpDatos.Enabled = true;
            this.cboEstado.Enabled = true;

            // Estableciendo los estados de los botones
            cambiarEstadoBotones(Opcion.Editar);

            this.tipoOperacion = OperacionMantenimiento.Editar;

            // Estableciendo focus al caja de texto de descripcion
            this.txtDescripcion.Focus();
        }

        private void abrir()
        {
            // Estableciendo estado de TagPage de Listado y datos
            this.tabPagListado.Enabled = false; this.tabPagDatos.Enabled = true;

            // Mostrar la segunda pagina del TabControl
            this.tabControl.SelectedIndex = 1;

            // Estableciendo los estados de los botones
            cambiarEstadoBotones(Opcion.Abrir);

            // Valida si seleccione algun componente
            if (this.dgvListado.CurrentRow != null && this.dgvListado.CurrentRow.Index > -1)
            {
                ListPersonalizada<Componente> listaComponentes = (ListPersonalizada<Componente>)this.dgvListado.DataSource;
                this.componenteActual = listaComponentes[this.dgvListado.CurrentRow.Index];

                this.txtDescripcion.Text = this.componenteActual.descripcion;
                this.cboEstado.Text = this.componenteActual.estado;
            }
        }

        private void cancelar()
        {
            if ( (this.tipoOperacion == OperacionMantenimiento.Editar) ||
                 (!this.grpDatos.Enabled))
            {
                this.cboCriterio.Text = DESCRIPCION;
                this.txtCriterio.Text = this.txtDescripcion.Text;
            }

            if (!this.txtCriterio.Text.Equals(string.Empty))
            {
                // Refrescar grilla
                listarComponentes(this.cboCriterio.Text, this.txtCriterio.Text);
            }

            // Estableciendo estado de TagPage de Listado y datos
            this.tabPagListado.Enabled = true; this.tabPagDatos.Enabled = false;

            // Mostrar la primera pagina del TabControl
            this.tabControl.SelectedIndex = 0;

            // Deshabilitando el grupoBox de datos
            this.grpDatos.Enabled = false;

            // Estableciendo los estados de los botones
            cambiarEstadoBotones(Opcion.Cancelar);

            // Estableciendo focus al caja de texto de busqueda
            this.txtCriterio.Focus();
        }

        private void grabar()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            try
            {
                if (validarEntrada()) { return; }

                // Solicitar confirmacion
                if (!Libreria.ShowMessageboxPregunta((this.tipoOperacion == OperacionMantenimiento.Nuevo ?
                                                                            "¿Estas seguro de registrar el componente?" :
                                                                            "¿Estas seguro de modificar el componente actual?"), TITULO)) { return; }


                // Estableciendo operacion a ser enviada al Servicio REST
                operacion = new Operacion();
                operacion.numero = this.tipoOperacion == OperacionMantenimiento.Nuevo ? Constantes.OPERACION_REGISTRAR_COMPONENTE : Constantes.OPERACION_MODIFICAR_COMPONENTE;

                operacion.componente = new Componente();
                operacion.componente.codigo = this.tipoOperacion == OperacionMantenimiento.Nuevo ? Constantes.VALOR_CERO : this.componenteActual.codigo;
                operacion.componente.descripcion = this.txtDescripcion.Text;
                operacion.componente.estado = this.cboEstado.SelectedValue.ToString();
                operacion.componente.fechaRegistro = DateTime.Now.ToString(Constantes.FORMATO_FECHAHORA);

                // Instanciando y ejecutando llamada al ServicioREST
                ConexionREST conexionREST = new ConexionREST();
                contenidoXML = conexionREST.ejecutarOperacion(operacion);

                // Obteniendo Objeto de Error
                OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

                // Validar si hay error
                if (operacionError != null)
                {
                    Libreria.ShowMessageboxError(operacionError.descripcion);
                    return;
                }

                OperacionResultado operacionResultado = contenidoXML.DeserializarTo<OperacionResultado>();

                string mensajeOK = this.tipoOperacion == OperacionMantenimiento.Nuevo ? "Registro guardado correctamente" : "Datos modificado correctamente";
                string mensajeError = this.tipoOperacion == OperacionMantenimiento.Nuevo ? "No se guardo los datos" : "No se actualizo los datos";


                if ((operacionResultado != null) &&
                    (operacionResultado.esOK.Equals(Constantes.SI)))
                {
                    Libreria.ShowMessageboxInfo(mensajeOK, TITULO);
                }
                else
                {
                    Libreria.ShowMessageboxError(mensajeError, TITULO);
                    return;
                }

                this.grpDatos.Enabled = false;

                // Estableciendo los estados de los botones
                cambiarEstadoBotones(Opcion.Grabar);
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }

        private void eliminar()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            try
            {
                // Solicitar confirmacion para eliminar el usuario
                if (!Libreria.ShowMessageboxPregunta("¿Esta seguro de eliminar a este Componente?", TITULO)) { return; }

                // Estableciendo operacion a ser enviada al Servicio REST
                operacion = new Operacion();
                operacion.numero = Constantes.OPERACION_ELIMINAR_COMPONENTE;

                operacion.tienda = new Tienda { codigo = this.componenteActual.codigo };

                // Instanciando y ejecutando llamada al ServicioREST
                ConexionREST conexionREST = new ConexionREST();
                contenidoXML = conexionREST.ejecutarOperacion(operacion);

                // Obteniendo Objeto de Error
                OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

                // Validar si hay error
                if (operacionError != null)
                {
                    Libreria.ShowMessageboxError(operacionError.descripcion);
                    return;
                }

                OperacionResultado operacionResultado = contenidoXML.DeserializarTo<OperacionResultado>();

                if ((operacionResultado != null) &&
                    (operacionResultado.esOK.Equals(Constantes.SI)))
                {
                    Libreria.ShowMessageboxInfo("Registro eliminado correctamente", TITULO);
                }
                else
                {
                    Libreria.ShowMessageboxError("No se elimino el Registro", TITULO);
                    return;
                }

                // Estableciendo estado de TagPage de Listado y datos
                this.tabPagListado.Enabled = true; this.tabPagDatos.Enabled = false;

                // Mostrar la primera pagina del TabControl
                this.tabControl.SelectedIndex = 0;

                this.grpDatos.Enabled = false;

                listarComponentes(string.Empty, string.Empty);

                // Estableciendo los estados de los botones
                cambiarEstadoBotones(Opcion.Eliminar);
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }

        private bool validarEntrada()
        {
            bool resultado = false;

            this.txtDescripcion.Text = this.txtDescripcion.Text.Trim();

            if (this.txtDescripcion.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtDescripcion, "Debe ingresar el campo Descripción", TITULO);
                return true;
            }

            return resultado;
        }

        private void cambiarEstadoBotones(Opcion tipoOpcion)
        {
            switch (tipoOpcion)
            {
                case Opcion.Abrir:
                    this.tbtnEditar.Enabled = true;
                    this.tbtnNuevo.Enabled = true;
                    this.tbtnEliminar.Enabled = true;
                    this.tbtnCancelar.Enabled = true;

                    this.tbtnAbrir.Enabled = false;
                    this.tbtnGrabar.Enabled = false;
                    break;
                case Opcion.Nuevo:
                    this.tbtnGrabar.Enabled = true;
                    this.tbtnCancelar.Enabled = true;

                    this.tbtnNuevo.Enabled = false;
                    this.tbtnAbrir.Enabled = false;
                    this.tbtnEditar.Enabled = false;
                    this.tbtnEliminar.Enabled = false;
                    break;
                case Opcion.Editar:
                    this.tbtnGrabar.Enabled = true;
                    this.tbtnCancelar.Enabled = true;

                    this.tbtnEditar.Enabled = false;
                    this.tbtnNuevo.Enabled = false;
                    this.tbtnEliminar.Enabled = false;
                    break;
                case Opcion.Grabar:
                    this.tbtnNuevo.Enabled = true;
                    this.tbtnEliminar.Enabled = true;
                    this.tbtnCancelar.Enabled = true;
                    this.tbtnEditar.Enabled = true;

                    this.tbtnGrabar.Enabled = false;
                    break;
                case Opcion.Cancelar:
                    //this.tbtnAbrir.Enabled = true;
                    this.tbtnNuevo.Enabled = true;

                    this.tbtnEliminar.Enabled = false;
                    this.tbtnCancelar.Enabled = false;
                    this.tbtnGrabar.Enabled = false;
                    this.tbtnEditar.Enabled = false;
                    break;
                case Opcion.Eliminar:
                    this.tbtnAbrir.Enabled = true;
                    this.tbtnNuevo.Enabled = true;

                    this.tbtnEliminar.Enabled = false;
                    this.tbtnCancelar.Enabled = false;
                    this.tbtnGrabar.Enabled = false;
                    this.tbtnEditar.Enabled = false;
                    break;
            }
        }

        private void limpiarTodo()
        {
            this.txtDescripcion.Text = string.Empty;
            this.cboEstado.Text = Constantes.ESTADO_DESCRIPCION_ACTIVO;
        }

        private void seleccionarComponente()
        {
            // Valida si seleccione algun componente
            if (this.dgvListado.CurrentRow != null && this.dgvListado.CurrentRow.Index > -1)
            {
                ListPersonalizada<Componente> listaComponentes = (ListPersonalizada<Componente>)this.dgvListado.DataSource;
                this.componenteActual = listaComponentes[this.dgvListado.CurrentRow.Index];

                this.DialogResult = DialogResult.OK;
            }
        }

        private void controlBotonesPorRol()
        {
            if (ParametrosAplicacion.ROL_ADMINISTRADOR.codigo.Equals(ParametrosAplicacion.USUARIO_ACTUAL.rol.codigo)) { return; }

            this.tbtnNuevo.Visible = false;
            this.tbtnEditar.Visible = false;
            this.tbtnEliminar.Visible = false;
            this.tbtnGrabar.Visible = false;

            this.ESTADO = Constantes.ESTADO_CODIGO_ACTIVO;
        }

        private void salir()
        {
            //this.Close();
            this.DialogResult = DialogResult.Cancel;
        }
        #endregion
    }
}
